package services.empregado;

import dao.IEmpregadoDAO;
import data.Dinheiro;
import data.Empregado;
import data.Sexo;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import services.BaseServices;
import util.Const;
import util.Util;
import util.Valida;

public class EmpregadoServices extends BaseServices
{
	private static final String
			ERR_CPF_DEVE_CONTER_SOMENTE_NUMEROS			= "ERR_CPF_DEVE_CONTER_SOMENTE_NUMEROS",
			ERR_CPF_INVALIDO							= "ERR_CPF_INVALIDO",
			ERR_CPF_JA_CADASTRADO						= "ERR_CPF_JA_CADASTRADO",
			ERR_CPF_NUMERO_DIGITOS						= "ERR_CPF_NUMERO_DIGITOS",
			ERR_CPF_VAZIO								= "ERR_CPF_VAZIO",
			ERR_DATA_ADMISSAO_DEPOIS_DATA_ATUAL			= "ERR_DATA_ADMISSAO_DEPOIS_DATA_ATUAL",
			ERR_DATA_ADMISSAO_VAZIO						= "ERR_DATA_ADMISSAO_VAZIO",
			ERR_DATA_DESLIGAMENTO_ANTES_DATA_ADMISSAO	= "ERR_DATA_DESLIGAMENTO_ANTES_DATA_ADMISSAO",
			ERR_DATA_DESLIGAMENTO_DEPOIS_DATA_ATUAL		= "ERR_DATA_DESLIGAMENTO_DEPOIS_DATA_ATUAL",
			ERR_DATA_NASC_DEPOIS_DATA_ATUAL				= "ERR_DATA_NASC_DEPOIS_DATA_ATUAL",
			ERR_DATA_NASC_VAZIO							= "ERR_DATA_NASC_VAZIO",
			ERR_IDADE_MENOR_QUE_O_MINIMO				= "ERR_IDADE_MENOR_QUE_O_MINIMO",
			ERR_NOME_TAMANHO_MAX						= "ERR_NOME_TAMANHO_MAX",
			ERR_NOME_VAZIO								= "ERR_NOME_VAZIO",
			ERR_SALARIO_ABAIXO_DO_MIN					= "ERR_SALARIO_ABAIXO_DO_MIN",
			ERR_SALARIO_ACIMA_DO_MAX					= "ERR_SALARIO_ACIMA_DO_MAX",
			ERR_SALARIO_VAZIO							= "ERR_SALARIO_VAZIO",
			ERR_SEXO_VAZIO								= "ERR_SEXO_VAZIO";

	static public void inserirEmpregado( IEmpregadoDAO empregadoDAO, Empregado empregado )
		throws FileNotFoundException
	{
		validarDadosEmpregado( empregadoDAO, empregado );
		empregadoDAO.inserirEmpregado( empregado );
	}

	static public void excluirEmpregado( IEmpregadoDAO empregadoDAO, String cpf )
		throws FileNotFoundException
	{
		empregadoDAO.excluirEmpregado( cpf );
	}

	static public Empregado getEmpregado( IEmpregadoDAO empregadoDAO, String cpf )
		throws FileNotFoundException
	{
		return empregadoDAO.getEmpregado( cpf );
	}
	
	static public List< Empregado > lerEmpregados( IEmpregadoDAO empregadoDAO )
		throws FileNotFoundException
	{
		return( new ArrayList<>( empregadoDAO.lerEmpregados().values() ) );
	}

	//-------------------------------------------------------------------------
	// métodos private
	//-------------------------------------------------------------------------	
	static private void validarDadosEmpregado( IEmpregadoDAO empregadoDAO, Empregado empregado ) 
		throws FileNotFoundException
	{
		validarCpf( empregado.getCpf(), empregadoDAO );
		validarNome( empregado.getNome() );
		validarDataNascimento( empregado.getDataNascimento() );		
		validarSexo( empregado.getSexo() );
		validarDataAdmissao( empregado.getDataAdmissao(), empregado.getDataNascimento() );
		validarSalario( empregado.getSalario() );
		validarDataDesligamento( empregado.getDataDesligamento(), empregado.getDataAdmissao() );
	}

	private static void validarCpf( String cpf, IEmpregadoDAO empregadoDAO ) throws FileNotFoundException 
	{
		check( !cpf.isEmpty(), Const.getString(ERR_CPF_VAZIO) );
		check( Util.isNumericInt( cpf ), Const.getString(ERR_CPF_DEVE_CONTER_SOMENTE_NUMEROS) );
		check( cpf.length() == Empregado.TAMANHO_CPF, String.format( Const.getString(ERR_CPF_NUMERO_DIGITOS), Empregado.TAMANHO_CPF) );
		check( Valida.isCpfValido( cpf ), Const.getString(ERR_CPF_INVALIDO) );
		check( !existeEmpregado( empregadoDAO, cpf ), Const.getString(ERR_CPF_JA_CADASTRADO) );
	}

	private static void validarNome( String nome )
	{
		check( !nome.isEmpty(), Const.getString(ERR_NOME_VAZIO) );
		check( nome.length() <= Empregado.TAMANHO_MAX_NOME, String.format( Const.getString(ERR_NOME_TAMANHO_MAX), Empregado.TAMANHO_MAX_NOME ) );
	}

	private static void validarDataNascimento( Calendar data )
	{
		check( data != null, Const.getString(ERR_DATA_NASC_VAZIO) );
		check( !data.after(Util.getDataAtual()), Const.getString(ERR_DATA_NASC_DEPOIS_DATA_ATUAL) );
	}

	private static void validarSexo( Sexo sexo)
	{
		check( sexo != Sexo.NAO_INFORMADO, Const.getString(ERR_SEXO_VAZIO) );
	}

	private static void validarSalario( Dinheiro salario )
	{
		check( salario != null, Const.getString(ERR_SALARIO_VAZIO) );
		check( !salario.isMenorQue(Empregado.SALARIO_MINIMO), String.format( Const.getString(ERR_SALARIO_ABAIXO_DO_MIN), Empregado.SALARIO_MINIMO ) );
		check( !salario.isMaiorQue(Empregado.SALARIO_MAXIMO), String.format( Const.getString(ERR_SALARIO_ACIMA_DO_MAX), Empregado.SALARIO_MAXIMO ) );
	}

	private static void validarDataAdmissao( Calendar dataAdmissao, Calendar dataNasc )
	{
		check( dataAdmissao != null, Const.getString(ERR_DATA_ADMISSAO_VAZIO) );
		check( !dataAdmissao.after(Util.getDataAtual()), Const.getString(ERR_DATA_ADMISSAO_DEPOIS_DATA_ATUAL) );
		
		int idadeDeAdmissao = Util.getDiferencaEmAnos( dataNasc, dataAdmissao );
		check( idadeDeAdmissao >= Empregado.IDADE_MINIMA_ADMISSAO, String.format( Const.getString(ERR_IDADE_MENOR_QUE_O_MINIMO), Empregado.IDADE_MINIMA_ADMISSAO ) );
	}

	private static void validarDataDesligamento( Calendar dataDeslig, Calendar dataAdmissao )
	{
		if( dataDeslig != null ) //Não é obrigatória
		{
			check( !dataDeslig.after( Util.getDataAtual() ), Const.getString(ERR_DATA_DESLIGAMENTO_DEPOIS_DATA_ATUAL) );
			check( dataDeslig.after( dataAdmissao ), Const.getString(ERR_DATA_DESLIGAMENTO_ANTES_DATA_ADMISSAO) );
		}
	}

	private static boolean existeEmpregado( IEmpregadoDAO empregadoDAO, String cpf )
		throws FileNotFoundException
	{
		return( empregadoDAO.getEmpregado( cpf ) != null );
	}
}
